/*
 * Copyright (c) 2011-2012, Two Trolls Entertainment
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of the Rhenium nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Two Trolls Entertainment BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <SDL/SDL_image.h>
#include <iostream>
#include "entity.h"
#include "mathhelper.h"
#include "utils.h"
#include "gui.h"

const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 640;
const int SCREEN_BPP = 32;
bool bFullscreen = false;


SDL_Event event;
SDL_Joystick *joysticks[4];

bool init_GL();

bool init()
{
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    {
        return false;
    }

    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );

    int joystickNum = SDL_NumJoysticks();
    if (joystickNum > 0)
    {
        for (int i=0; i < joystickNum; i++)
            joysticks[i] = SDL_JoystickOpen(i);
    }
    if (SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_OPENGL) == NULL)
    {
        return false;
    }

    if (init_GL() == false)
    {
        return false;
    }

    SDL_WM_SetCaption("Rhenium", NULL);

    return true;
}

bool init_GL()
{
    glClearColor( 0, 0, 0, 0 );

    //Set projection
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1 );

    //Initialize modelview matrix
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    if( glGetError() != GL_NO_ERROR )
    {
        return false;
    }

    return true;
}

bool toggleFullscreen()
{
    if (bFullscreen)
    {
        if (SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL) == NULL)
        {
            return false;
        }
    }
    else
    {
        if(SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL | SDL_FULLSCREEN) == NULL)
        {
            return false;
        }
    }
    bFullscreen = !bFullscreen;
    return true;
}

void cleanup()
{
    for (int i=0; i < SDL_NumJoysticks(); i++)
        SDL_JoystickClose(joysticks[i]);
    SDL_Quit();
}

int main(int argc, char *args[])
{
    bool running = true;

    if (init() == false)
    {
        return 1;
    }

    EntityPlayer *player = new EntityPlayer(Vec2F(10,10));
    player->addInputHandler(Utils::INPUT_JOYSTICK, 0);

    EntityManager *manager = new EntityManager();

    Utils::Timer timer;
    int lastUpdate = 0, lastFire = 0;
    timer.start();

    SDL_ShowCursor(0); //Disable cursor

    //Main game loop
    while (running)
    {
        //Loop through all events
        while (SDL_PollEvent( &event ))
        {

            player->handleMovement(event);

            if (event.type == SDL_KEYDOWN)
            {
                switch (event.key.keysym.sym)
                {
                    case SDLK_ESCAPE: running = false; break;
                    case SDLK_F11: toggleFullscreen(); break;
                    default: break;
                }
            }

            else if (event.type == SDL_MOUSEMOTION)
            {

            }

            //If window is closed, then end
            else if (event.type == SDL_QUIT)
            {
                //Quit the program
                running = false;
            }
        }

        if (player->inputHandler->fireHeld() && (timer.getTicks() - lastFire) > 100)
        {
            EntityBullet bullet(player->getX(), player->getY());
            EntityBullet bullet2(player->getX() + 49, player->getY());

            manager->addBullet(bullet);
            manager->addBullet(bullet2);
            lastFire = timer.getTicks();
        }

        player->tick(timer.getTicks() - lastUpdate);
        manager->tick(timer.getTicks() - lastUpdate);

        glClear(GL_COLOR_BUFFER_BIT); // clear screen

        player->render(timer.getTicks());
        manager->render();

        //swap buffers
        SDL_GL_SwapBuffers();

        lastUpdate = timer.getTicks();

        SDL_Delay(10);
    }

    delete player;

    cleanup();
    return 0;
}
